/**
 * 
 */
package com.dalonedrow.rpg.base.systems;

import com.dalonedrow.engine.sprite.base.SimpleVector2;

/**
 * Interface for Equipment methods
 * @author DaLoneDrau
 * @param <IO> the interactive object class
 * @param <SCRIPT> the script class
 */
public interface Equipment<IO, SCRIPT> {
	/**
	 * Determines if an interactive object can equip an item.
	 * @param target the target interactive object
	 * @param toequip the item to be equipped
	 * @return true if the interactive object can equip the item; false
	 *         otherwise
	 * @throws Exception if an error occurs
	 */
	boolean canEquipItem(IO target, IO toequip) throws Exception;
	/**
	 * Computes the damage occurred during an attack, and then applies the
	 * damage and sends messages to involved entities.
	 * @param ioSource the attacker
	 * @param ioTarget the target
	 * @param ratioaim ???
	 * @param position ???
	 * @return <code>float</code>
	 * @throws Exception if an error occurs
	 */
	float computeDamages(IO ioSource, IO ioTarget, float ratioaim,
			SimpleVector2 position) throws Exception;
	/**
	 * Attempts to equip the target interactive object with an item.
	 * @param target the target interactive object
	 * @param toequip the item to be equipped
	 * @throws Exception if an error occurs
	 */
	void equipItem(IO target, IO toequip) throws Exception;
	/**
	 * Gets the value of the equipment's attribute or skill modifier. If the
	 * modifier is a whole modifier, such as +2, then that value is returned. If
	 * the modifier is a percentage, such as 5%, then the value returned is the
	 * modifier applied to the original value, such as 5% of 18, which is 0.9.
	 * @param io the interactive piece of equipment
	 * @param ident the id of the attribute or skill
	 * @param trueVal the original value of the attribute or skill. used to
	 *        apply percentage modifiers
	 * @return <code>float</code>
	 * @throws Exception if an error occurs
	 */
	float getEquipmentModifier(IO io, int ident, float trueVal)
			throws Exception;
	/**
	 * Gets a "fresh" item.
	 * @param script the item's script
	 * @return {@link IO}
	 * @throws Exception if an error occurs
	 */
	IO getFreshItem(SCRIPT script) throws Exception;
	/**
	 * Parses the hit value from a string of text.
	 * @param text the text
	 * @return <code>float</code>
	 */
	float getHitValue(char[] text);
	/**
	 * Parses the hit value from a string of text.
	 * @param text the text
	 * @return <code>float</code>
	 */
	float getHitValue(String text);
	/**
	 * Gets the equipment modifier for a specific characteristic element
	 * (Strength, THAC0, etc.).
	 * @param item the item
	 * @param element the characteristic element
	 * @return <code>float</code>
	 */
	/*
	 * float getEquipmentModifier(IO item, long element);
	 */
	/**
	 * Gets the equipment modifier for a specific characteristic element
	 * (Strength, THAC0, etc.) and apply it as a percentile bonus or penalty
	 * based on the original value. For instance, an item that applies a 10%
	 * bonus to Strength would return a value of 1.6 when applied to an original
	 * score of 16.
	 * @param item the item
	 * @param element the characteristic element
	 * @param trueval the original score
	 * @return <code>float</code>
	 */
	/*
	 * float getEquipmentModifierPercentile( IO item, long element, float
	 * trueval);
	 */
	/**
	 * Gets the object type flag that corresponds to a specific character code.
	 * @param c the character
	 * @return <code>int</code>
	 * @throws Exception if the character prefix is invalid
	 */
	int getObjectTypeFlag(char c) throws Exception;
	/**
	 * Gets the weapon type the player is equipped with.
	 * @param pc the player
	 * @return <code>int</code>
	 * @throws Exception if an error occurs
	 */
	int getPlayerWeaponType(IO pc)
			throws Exception;
	/**
	 * Gets the value of the "special" modifier applied to an item.
	 * @param item the item
	 * @param val the id of the "special" modifier
	 * @return <code>float</code>
	 */
	float getSpecialValue(IO item,
			long val);
	/**
	 * Identifies all equipment for a player.
	 * @param pc the player
	 */
	void identifyAll(IO pc);
	/** Initializes all equipment information. */
	void init();
	/**
	 * Initializes the equipment data structure for an item with default values.
	 * @param item the item
	 * @param isSpecial if true, the item has a "special" modifier
	 * @param specialElement the "special" modifier to be applied; can be null
	 * @param specialVal the value of the "special" modifier; ignored if not a
	 *        "special" item
	 * @param specialFlags any flags applied for the "special" modifier
	 */
	/*
	 * void initEquipment(IO item, boolean isSpecial, String specialElement,
	 * float specialVal, long specialFlags);
	 */
	/**
	 * Determines if a player has an item equipped.
	 * @param pc the player
	 * @param item the item
	 * @return true if the player is equipped with an item; false otherwise
	 * @throws Exception if an error occurs
	 */
	boolean isPlayerEquippedWithItem(IO pc, IO item)
			throws Exception;
	/**
	 * Handles events when a player equips a weapon.
	 * @param pc the player
	 */
	void launchPlayerReadyWeapon(IO pc);
	/**
	 * Handles events when a player unequips a weapon.
	 * @param pc the player
	 */
	void launchPlayerUnReadyWeapon(IO pc);
	/**
	 * Recreates the player's appearance based on the equipment they have on.
	 * @param pc the player
	 */
	void recreatePlayerAppearance(IO pc);
	/**
	 * Releases an equipped item from the player.
	 * @param pc the player
	 * @param id the item's id
	 * @throws Exception if an error occurs
	 */
	void release(IO pc, long id)
			throws Exception;
	/**
	 * Releases an equipped item from player.
	 * @param id the item's id
	 * @param pc the player
	 * @throws Exception if an error occurs
	 */
	void release(long id, IO pc)
			throws Exception;
	/**
	 * Releases all equipment ids.
	 * @param io the interactive object
	 */
	void releaseAll(IO io);
	/**
	 * Releases equipment structure for a specific interactive object.
	 * @param io the interactive object
	 */
	void releaseEquipItem(IO io);
	/**
	 * Removes all special equipment properties for a specific interactive
	 * object.
	 * @param io the interactive object
	 */
	void removeAllSpecial(IO io);
	/**
	 * Removes a class restriction on an item.
	 * @param item the item
	 * @param restriction the class restriction
	 */
	void removeClassRestriction(IO item, int restriction);
	/**
	 * Removes a race restriction on an item.
	 * @param item the item
	 * @param restriction the race restriction
	 */
	void removeRaceRestriction(IO item, int restriction);
	/**
	 * Sets a class restriction on an item.
	 * @param item the item
	 * @param restriction the class restriction
	 */
	void setClassRestriction(IO item, int restriction);
	void setEquip(IO io, String param1,
			String param2, float val, int flags);
	/**
	 * Sets the equipment modifier on an item.
	 * @param io the item
	 * @param element the modifier type
	 * @param val the value of the modifier
	 * @param flag and flags to be set
	 */
	void setEquipmentModifier(IO io, int element,
			float val, int flag);
	/**
	 * Sets/removes an object type flag on an item that corresponds to a
	 * specific character code.
	 * @param item the item
	 * @param c the character code indicating the object type flag
	 * @param isSet if true, the flag should be set; otherwise the flag is
	 *        removed
	 * @throws Exception if an error occurs
	 */
	void setObjectType(IO item, char c,
			boolean isSet) throws Exception;
	/**
	 * Sets/removes an object type flag on an item that corresponds to a
	 * specific character code.
	 * @param item the item
	 * @param type the object type flag
	 * @param isSet if true, the flag should be set; otherwise the flag is
	 *        removed
	 * @throws Exception if an error occurs
	 */
	void setObjectType(IO item, int type,
			boolean isSet) throws Exception;
	/**
	 * Sets a race restriction on an item.
	 * @param item the item
	 * @param restriction the race restriction
	 */
	void setRaceRestriction(IO item, int restriction);
	/**
	 * Handles events when an attack happens.
	 * @param ioSource the attacker
	 * @param ioWeapon the weapon used
	 * @param ratioaim ???
	 * @param showBlood if true blood is shown; false otherwise
	 * @param targ the target's id
	 * @return true if the attack is successful; false otherwise
	 * @throws Exception if an error occurs
	 */
	boolean strikeCheck(IO ioSource,
			IO ioWeapon, float ratioaim, boolean showBlood,
			int targ) throws Exception;
	/**
	 * Unequips an item.
	 * @param target the target object
	 * @param tounequip the item being unequipped
	 * @param isDestroyed if true, the item is destroyed; otherwise the item
	 *        still exists and is placed somewhere
	 * @throws Exception if an error occurs
	 */
	void unequip(IO target,
			IO tounequip, boolean isDestroyed)
			throws Exception;
	/**
	 * Unequips all items from the player.
	 * @param pc the player
	 * @throws Exception if an error occurs
	 */
	void unequipAllOnPlayer(IO pc)
			throws Exception;
	/**
	 * Unequips the player's weapon.
	 * @param pc the player
	 * @throws Exception if an error occurs
	 */
	void unequipPlayerWeapon(IO pc)
			throws Exception;
}
